/*
 * Copyright © 2019-2020  Whale Cloud, Inc. All Rights Reserved.
 *
 * Notice: Whale Cloud Inc copyrights this specification.
 * No part of this specification may be reproduced in any form or means,
 * without the prior written consent of Whale Cloud Inc.
 *
 */
package com.wteam.modules.system.service.impl;

import com.wteam.modules.system.domain.dto.CusPage;
import com.wteam.modules.system.domain.mapper.CourseMapper;
import com.wteam.modules.system.domain.mapper.TeacherMapper;
import com.wteam.modules.system.domain.mapper.UserMapper;
import com.wteam.modules.system.repository.CourseRepository;
import com.wteam.modules.system.repository.TeacherRepository;
import com.wteam.modules.system.repository.UserRepository;
import com.wteam.modules.system.service.TeacherClassMapService;
import com.wteam.modules.system.domain.TeacherClassMap;
import com.wteam.modules.system.domain.dto.TeacherClassMapDTO;
import com.wteam.modules.system.domain.criteria.TeacherClassMapQueryCriteria;
import com.wteam.modules.system.domain.mapper.TeacherClassMapMapper;
import com.wteam.modules.system.repository.TeacherClassMapRepository;
import com.wteam.exception.BadRequestException;
import com.wteam.utils.*;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.cache.annotation.*;
import lombok.RequiredArgsConstructor;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

/**
 * 教师班级映射 业务实现层.
 *
 * @author herry_wong
 * @since 2020-12-29
 */
@Service
@RequiredArgsConstructor
@CacheConfig(cacheNames = "teacherClassMap")
@Transactional(readOnly = true, rollbackFor = Exception.class)
public class TeacherClassMapServiceImpl implements TeacherClassMapService {

    private final TeacherClassMapRepository teacherClassMapRepository;
    private final TeacherClassMapMapper teacherClassMapMapper;

    private final TeacherRepository teacherRepository;
    private final TeacherMapper teacherMapper;

    private final CourseRepository courseRepository;
    private final CourseMapper courseMapper;

    private final UserRepository userRepository;
    private final UserMapper userMapper;

    private final RedisUtils redisUtils;

    @Override
    public Map<String,Object> queryAll(TeacherClassMapQueryCriteria criteria, Pageable pageable){
        Page<TeacherClassMap> page = teacherClassMapRepository.findAll((root, criteriaQuery, criteriaBuilder) ->  QueryHelper.andPredicate(root, criteria, criteriaBuilder), pageable);
        Page<TeacherClassMapDTO> teacherClassMapDTOPage = page.map(teacherClassMapMapper::toDto);
        Page<TeacherClassMapDTO> cusPage = new CusPage<>(teacherClassMapDTOPage);
        for (TeacherClassMapDTO teacherClassMapDTO: cusPage){
            Collections.replaceAll(cusPage.getContent(),teacherClassMapDTO,findDTOById(teacherClassMapDTO.getId()));
        }
        return PageUtil.toPage(cusPage);
    }

    @Override
    public List<TeacherClassMapDTO> queryAll(TeacherClassMapQueryCriteria criteria){
        return teacherClassMapMapper.toDto(teacherClassMapRepository.findAll((root, criteriaQuery, criteriaBuilder) ->  QueryHelper.andPredicate(root,criteria,criteriaBuilder)));
    }

    @Override
//    @Cacheable(key = "'id:' + #p0")
    public TeacherClassMapDTO findDTOById(Long id) {
        TeacherClassMap teacherClassMap = teacherClassMapRepository.findById(id).orElse(null);
        ValidUtil.notNull(teacherClassMap, TeacherClassMap.ENTITY_NAME, "id", id);
        TeacherClassMapDTO teacherClassMapDTO = teacherClassMapMapper.toDto(teacherClassMap);
        teacherClassMapDTO.setCourseDTO(courseMapper.toDto(courseRepository.findById(teacherClassMap.getCourseId()).orElse(null)));
        teacherClassMapDTO.setTeacherDTO(teacherMapper.toDto(teacherRepository.findById(teacherClassMap.getTeacherId()).orElse(null)));
        teacherClassMapDTO.getTeacherDTO().setUserDTO(
                userMapper.toDto(userRepository.findById(teacherClassMap.getTeacherId()).orElse(null))
        );
        return teacherClassMapDTO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public TeacherClassMapDTO create(TeacherClassMap resources) {
        TeacherClassMapDTO teacherClassMapDTO = new TeacherClassMapDTO();
        if (teacherClassMapRepository.
                findByTeacherIdAndClassIdAndCourseId(resources.getTeacherId(),
                        resources.getClassId(),
                        resources.getCourseId()) == null){
            teacherClassMapDTO = teacherClassMapMapper.toDto(teacherClassMapRepository.save(resources));
            teacherClassMapDTO.setCourseDTO(courseMapper.toDto(courseRepository.findById(resources.getCourseId()).orElse(null)));
            teacherClassMapDTO.setTeacherDTO(teacherMapper.toDto(teacherRepository.findById(resources.getTeacherId()).orElse(null)));
            teacherClassMapDTO.getTeacherDTO().setUserDTO(
                    userMapper.toDto(userRepository.findById(teacherClassMapDTO.getTeacherId()).orElse(null))
            );
        }else {
            teacherClassMapDTO.setMsg("该老师在该班已经教授了该课程");
        }
        return teacherClassMapMapper.toDto(teacherClassMapRepository.save(resources));
    }

    @Override
    @CacheEvict(key = "'id:' + #p0.id")
    @Transactional(rollbackFor = Exception.class)
    public void update(TeacherClassMap resources) {
        TeacherClassMap teacherClassMap = teacherClassMapRepository.findById(resources.getId()).orElse(null);
        ValidUtil.notNull(teacherClassMap, TeacherClassMap.ENTITY_NAME, "id",resources.getId());

        teacherClassMap.copy(resources);
        teacherClassMapRepository.save(teacherClassMap);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteAll(Set<Long> ids) {
        redisUtils.delByKeys("teacherClassMap::id:", ids);
        teacherClassMapRepository.logicDeleteInBatchById(ids);
    }

    @Override
    public void download(List<TeacherClassMapDTO> queryAll, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (TeacherClassMapDTO teacherClassMap : queryAll) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("教师id", teacherClassMap.getTeacherId());
            map.put("班级id", teacherClassMap.getClassId());
            map.put("是否结课", teacherClassMap.getFinish());
            map.put("创建时间", teacherClassMap.getCreatedAt());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }
}